import { AsyncStorage } from 'react-native';
import Request from "../utils/Request";
import RouterServer from "../utils/RouterServer";
import { kAuthorization, kContentType } from "../constant";
import constant from "../utils/constant";
import { checkRole } from "../utils/tools";
const moment = require("moment");
const { Toast } = require('antd-mobile');
const STORAGE_KEY = "STORAGE_KEY_auth";
const model = {
    namespace: 'auth',
    state: {
        access_token: null,
        expires_in: null,
        refresh_token: null,
        scope: null,
        token_type: null,
        authorities: null,
        loading: true,
        expires_at: null,
        firstLaunch: true,
        areaList: [],
        selectArea: null,
        userInfo: null,
        myGroups: [],
        groupNews: [],
        notInGroupsDTOS: null,
    },
    reducers: {
        save(state, { payload }) {
            return Object.assign({}, state, payload);
        }
    },
    effects: {
        *saveToStorage({ payload }, { call }) {
            yield call(AsyncStorage.setItem, STORAGE_KEY, JSON.stringify(payload));
        },
        *restoreFromStorage({ payload }, { call, put, select }) {
            const data = yield call(AsyncStorage.getItem, STORAGE_KEY);
            yield put({
                type: 'save',
                payload: Object.assign({}, JSON.parse(data))
            });
            const auth = yield select(state => state.auth);
            const isLogin = moment.unix(auth.expires_at).diff(moment(), 'seconds') > 0;
            if (auth.firstLaunch) {
                yield call(RouterServer.replace, 'guide');
            }
            else if (isLogin) {
                yield call(RouterServer.replace, 'tab');
            }
            else {
                yield call(RouterServer.replace, 'auth');
            }
        },
        *loading({ paylod }, { put }) {
            yield put({ type: 'save', payload: { loading: true } });
        },
        *end({ paylod }, { put }) {
            yield put({ type: 'save', payload: { loading: false } });
        },
        *firstLaunch({ payload }, { put, call, select }) {
            const auth = yield select(state => state.auth);
            auth.firstLaunch = true;
            yield put({
                type: 'save',
                payload: Object.assign({}, auth)
            });
            yield put({
                type: 'saveToStorage',
                payload: Object.assign({}, auth)
            });
        },
        *oauth({ payload }, { call, put, select }) {
            let p = { params: Object.assign({}, payload) };
            p[kContentType] = 'application/json';
            yield put({ type: 'loading' });
            let result = yield call(Request.post, Request.getApi().oauth, p);
            yield put({ type: 'end' });
            if (result) {
                result['expires_at'] = moment().add(1, 'M').unix();
                result.token_type = 'Bearer';
                let auth = yield select(state => state.auth);
                let params = {
                    Authorization: result.token_type + ' ' + result.access_token,
                    loginName: payload.username
                };
                const userInfo = yield call(Request.get, Request.getApi().userInfo, params);
                if (userInfo) {
                    auth = result;
                    auth.userInfo = userInfo;
                    auth.firstLaunch = false;
                    if (checkRole(userInfo.roles)) {
                        yield put({ type: 'save', payload: Object.assign({}, auth) });
                        auth = yield select(state => state.auth);
                        yield put({ type: 'saveToStorage', payload: Object.assign({}, auth) });
                        yield call(RouterServer.replace, 'tab');
                    }
                    else {
                        Toast.fail('未授权!请重新登录', 1);
                    }
                }
            }
        },
        *fetchAreaList({ payload }, { call, put, select }) {
            if (!payload) {
                payload = {};
            }
            let auth = yield select(state => state.auth);
            payload['Authorization'] = `${auth.token_type} ${auth.access_token}`;
            const data = yield call(Request.get, Request.getApi().areaList, payload);
            if (data && Array.isArray(data['content'])) {
                auth.areaList = data['content'];
                auth.selectArea = auth.areaList[0];
                yield put({
                    type: 'save',
                    payload: Object.assign({}, auth)
                });
                auth = yield select(state => state.auth);
                if (auth.selectArea) {
                    yield put({
                        type: 'post/fetchData',
                        payload: Object.assign({ areaId: auth.selectArea.id }, payload)
                    });
                }
            }
        },
        *changeSelectArea({ payload }, { call, put, select }) {
            let auth = yield select(state => state.auth);
            auth.selectArea = payload.selectArea;
            yield put({ type: 'save', payload: Object.assign({}, auth) });
            auth = yield select(state => state.auth);
            if (!payload.notFecthPost) {
                yield put({
                    type: 'post/fetchData',
                    payload: Object.assign({}, payload, { areaId: auth.selectArea.id })
                });
            }
        },
        *fetchData({ payload }, { call, put, select }) {
            yield put({ type: 'fetchAreaList', payload });
        },
        *fetchGroupList({ payload }, { call, put, select }) {
            const auth = yield select(state => state.auth);
            if (!payload)
                payload = { pi: 1, ps: 5 };
            yield put({ type: 'save', payload: { loading: true } });
            payload['Authorization'] = auth.token_type + ' ' + auth.access_token;
            payload['userId'] = auth.userInfo.id;
            let loadMore = false;
            if (payload['pi'] !== 1 && auth.notInGroupsDTOS.last !== true) {
                loadMore = true;
            }
            const data = yield call(Request.get, Request.getApi().myGroupList + `/${auth.userInfo.id}`, payload);
            yield put({ type: 'save', payload: { loading: false } });
            if (data) {
                let myGroups = [];
                data.myGroups.map((i => {
                    if (i.group) {
                        myGroups.push(Object.assign({}, i.group, { vipNumber: i.vipNumber }));
                    }
                }));
                let groupNews = [];
                data.myGroups.map((i => {
                    if (i.groupNews) {
                        groupNews.push(Object.assign({}, i.groupNews, { group: i.group }));
                    }
                }));
                const notInGroupsDTOS = data.notInGroupsDTOS;
                if (false !== false) {
                    auth.notInGroupsDTOS.content = auth.notInGroupsDTOS.content.concat(notInGroupsDTOS.content);
                }
                else {
                    auth.notInGroupsDTOS = notInGroupsDTOS;
                }
                yield put({
                    type: 'save',
                    payload: {
                        myGroups,
                        notInGroupsDTOS: auth.notInGroupsDTOS,
                        groupNews
                    }
                });
            }
        },
        *signOut({ payload }, { put, select, call }) {
            let auth = yield select(state => state.auth);
            auth = null;
            yield put({ type: 'save', payload: Object.assign({}, auth) });
            yield put({ type: 'saveToStorage', payload: Object.assign({}, auth) });
            yield call(RouterServer.replace, 'auth', { from: 'tab' });
        },
        *joinGroup({ payload }, { put, select, call }) {
            yield put({ type: 'loading' });
            const auth = yield select(state => state.auth);
            payload['Authorization'] = auth.token_type + ' ' + auth.access_token;
            payload['Content-Type'] = `application/json`;
            payload['params'] = Number(payload.groupId);
            const result = yield call(Request.post, Request.getApi().groupJoin + `/${auth.userInfo.id}`, payload);
            yield put({ type: 'end' });
            yield call(RouterServer.pop);
        },
        *leaveGroup({ payload }, { put, select, call }) {
            yield put({ type: 'loading' });
            const auth = yield select(state => state.auth);
            payload['userId'] = auth.userInfo.id;
            payload['Authorization'] = auth.token_type + ' ' + auth.access_token;
            const result = yield call(Request.del, Request.getApi().groupLeave, payload);
            yield put({ type: 'end' });
        },
        *upDataUserInfo(data, { put, select, call }) {
            let payload = data.payload;
            const auth = yield select(state => state.auth);
            const file = payload.file;
            let avatar = payload.avatar;
            if (file) {
                const res = yield call(Request.post, Request.getApi().upload + `/avatar`, { file });
                if (res) {
                    avatar = Request.checkImageUrl(res.url) + '';
                }
                delete payload.file;
            }
            payload.avatar = avatar;
            let params = { params: Object.assign({}, payload) };
            params[kAuthorization] = auth.token_type + ' ' + auth.access_token;
            params[kContentType] = 'application/json';
            const result = yield call(Request.put, Request.getApi().userInfoWithId + `/${payload.id}`, params);
            if (result) {
                Toast.success('用户信息更新成功!!!', constant.ToastDuration);
            }
        },
        *freshUserInfo({ payload }, { call, put, select }) {
            let auth = yield select(state => state.auth);
            if (!payload)
                payload = {};
            payload[kAuthorization] = auth.token_type + ' ' + auth.access_token;
            const result = yield call(Request.get, Request.getApi().userInfoWithId + `/${auth.userInfo.id}`, payload);
            if (result) {
                auth.userInfo = result;
                yield put({
                    type: 'save',
                    payload: Object.assign({}, auth)
                });
                yield put({ type: 'saveToStorage', payload: Object.assign({}, auth) });
            }
        },
        *changePassword({ payload }, { call, put, select }) {
            const auth = yield select(state => state.auth);
            let params = { params: Object.assign({}, payload) };
            params[kAuthorization] = auth.token_type + ' ' + auth.access_token;
            params[kContentType] = 'application/json';
            const res = yield call(Request.put, Request.getApi().changePassword + `/${auth.userInfo.id}`, params);
            if (res) {
                yield put({
                    type: 'signOut',
                    payload: {}
                });
            }
        },
    },
    subscriptions: {
        setup({ dispatch }) {
            dispatch({
                type: 'restoreFromStorage'
            });
        }
    },
};
export default model;
